from flask import Flask, request, jsonify, render_template, send_from_directory
from flask_cors import CORS
import os
import base64
import requests
import json
from werkzeug.utils import secure_filename
import time

# 导入配置
try:
    from config import SHILIUAI_APPCODE
except ImportError:
    SHILIUAI_APPCODE = ""
    print("⚠️ 未找到config.py文件，请创建配置文件并填入您的API密钥")

app = Flask(__name__)
CORS(app)

# 配置上传文件夹
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff', 'pdf'}

if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024  # 5MB max file size

# OCR API配置 - 优先使用十六AI
OCR_APIS = [
    {
        'name': '十六AI_OCR',
        'url': 'https://ocr-api.shiliuai.com/api/general_ocr/v1',
        'type': 'shiliuai',
        'appcode': SHILIUAI_APPCODE,
        'timeout': 30
    },
    {
        'name': 'OCR.space',
        'url': 'https://api.ocr.space/parse/image',
        'type': 'ocrspace',
        'key': 'helloworld',
        'timeout': 30
    },
    {
        'name': 'OCR.space_backup',
        'url': 'https://api.ocr.space/parse/image',
        'type': 'ocrspace',
        'key': 'K87899142388957',
        'timeout': 30
    }
]

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def call_shiliuai_ocr(file_path, api_config):
    """调用十六AI OCR API"""
    try:
        # 图片转base64
        with open(file_path, 'rb') as f:
            image_data = f.read()
            image_base64 = base64.b64encode(image_data).decode('utf8')
        
        # 请求头
        headers = {
            'Authorization': f'APPCODE {api_config["appcode"]}',
            'Content-Type': 'application/json'
        }
        
        # 请求体
        data = {
            "image_base64": image_base64,
            "return_position": True  # 请求返回位置信息
        }
        
        print(f"🔍 调用十六AI OCR API...")
        response = requests.post(
            api_config['url'],
            headers=headers,
            json=data,
            timeout=api_config['timeout']
        )
        
        if response.status_code == 200:
            result = response.json()
            print(f"📍 十六AI API响应: {json.dumps(result, ensure_ascii=False, indent=2)}")
            
            if result.get('success', False):
                # 解析十六AI的响应格式
                text_lines = []
                text_overlay_lines = []
                
                if 'data' in result and 'results' in result['data']:
                    for item in result['data']['results']:
                        text_lines.append(item.get('text', ''))
                        
                        # 构建坐标信息
                        if 'position' in item:
                            position = item['position']
                            # 十六AI返回的是四个点的坐标
                            if len(position) >= 4:
                                # 计算边界框
                                x_coords = [p[0] for p in position]
                                y_coords = [p[1] for p in position]
                                
                                left = min(x_coords)
                                top = min(y_coords)
                                width = max(x_coords) - left
                                height = max(y_coords) - top
                                
                                # 构建类似OCR.space的格式
                                text_overlay_lines.append({
                                    "Words": [{
                                        "WordText": item.get('text', ''),
                                        "Left": left,
                                        "Top": top,
                                        "Width": width,
                                        "Height": height
                                    }],
                                    "MaxHeight": height,
                                    "MinTop": top
                                })
                
                text = '\n'.join(text_lines)
                text_overlay = {
                    "Lines": text_overlay_lines,
                    "HasOverlay": True,
                    "Source": "ShiliuAI"
                }
                
                return {
                    'success': True,
                    'text': text,
                    'confidence': 0.95,
                    'api_used': '十六AI_OCR',
                    'text_overlay': text_overlay,
                    'raw_response': result
                }
            else:
                error_msg = result.get('message', '十六AI OCR识别失败')
                print(f"❌ 十六AI API错误: {error_msg}")
                
        else:
            print(f"❌ 十六AI API HTTP错误: {response.status_code}")
            
    except Exception as e:
        print(f"❌ 十六AI API调用异常: {str(e)}")
    
    return None

def call_ocrspace_api(file_path, api_config):
    """调用OCR.space API"""
    try:
        with open(file_path, 'rb') as f:
            payload = {
                'apikey': api_config['key'],
                'language': 'chs',
                'isOverlayRequired': True,
                'detectOrientation': True,
                'scale': True,
                'OCREngine': 2,
                'isTable': False
            }
            
            files = {
                'file': (os.path.basename(file_path), f, 'image/jpeg')
            }
            
            response = requests.post(
                api_config['url'],
                files=files,
                data=payload,
                timeout=api_config['timeout']
            )
            
            if response.status_code == 200:
                result = response.json()
                
                if result.get('IsErroredOnProcessing', True) == False:
                    parsed_results = result.get('ParsedResults', [])
                    if parsed_results:
                        parsed_result = parsed_results[0]
                        text = parsed_result.get('ParsedText', '').strip()
                        text_overlay = parsed_result.get('TextOverlay', {})
                        
                        if text:
                            return {
                                'success': True,
                                'text': text,
                                'confidence': 0.9,
                                'api_used': api_config['name'],
                                'text_overlay': text_overlay if text_overlay else None,
                                'raw_response': result
                            }
                        
    except Exception as e:
        print(f"❌ OCR.space API调用异常: {str(e)}")
    
    return None

def call_ocr_api(file_path, max_retries=3):
    """调用OCR API - 优先使用十六AI"""
    
    for api_config in OCR_APIS:
        # 检查十六AI的APPCODE是否配置
        if api_config['type'] == 'shiliuai' and not api_config.get('appcode'):
            print(f"⚠️ 跳过 {api_config['name']} - 未配置APPCODE")
            continue
            
        for attempt in range(max_retries):
            try:
                print(f"尝试使用 {api_config['name']} API (第{attempt + 1}次)")
                
                result = None
                if api_config['type'] == 'shiliuai':
                    result = call_shiliuai_ocr(file_path, api_config)
                elif api_config['type'] == 'ocrspace':
                    result = call_ocrspace_api(file_path, api_config)
                
                if result and result.get('success'):
                    print(f"✅ OCR识别成功，使用API: {api_config['name']}")
                    return result
                    
            except Exception as e:
                print(f"API调用异常: {str(e)}")
                if attempt < max_retries - 1:
                    time.sleep(2)
    
    return {
        'success': False,
        'error': '所有OCR API都无法使用',
        'text': '',
        'text_overlay': None
    }



@app.route('/')
def index():
    return render_template('index.html')

@app.route('/static/<path:filename>')
def static_files(filename):
    return send_from_directory('static', filename)

@app.route('/api/ocr', methods=['POST'])
def ocr_api():
    try:
        if 'file' not in request.files:
            return jsonify({'success': False, 'error': '没有上传文件'})
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'success': False, 'error': '没有选择文件'})
        
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            timestamp = str(int(time.time()))
            filename = f"{timestamp}_{filename}"
            file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(file_path)
            
            print(f"📁 文件已保存: {file_path}")
            
            # 调用OCR API
            result = call_ocr_api(file_path)
            
            if result['success']:
                return jsonify({
                    'success': True,
                    'text': result['text'],
                    'confidence': result.get('confidence', 0.9),
                    'api_used': result.get('api_used', 'Unknown'),
                    'text_overlay': result.get('text_overlay'),
                    'filename': filename
                })
            else:
                return jsonify({
                    'success': False,
                    'error': result.get('error', 'OCR识别失败')
                })
        else:
            return jsonify({'success': False, 'error': '不支持的文件格式'})
            
    except Exception as e:
        print(f"OCR API错误: {str(e)}")
        return jsonify({'success': False, 'error': f'服务器错误: {str(e)}'})

@app.route('/api/batch_ocr', methods=['POST'])
def batch_ocr_api():
    try:
        if 'files' not in request.files:
            return jsonify({'success': False, 'error': '没有上传文件'})
        
        files = request.files.getlist('files')
        if not files:
            return jsonify({'success': False, 'error': '没有选择文件'})
        
        results = []
        
        for file in files:
            if file and allowed_file(file.filename):
                filename = secure_filename(file.filename)
                timestamp = str(int(time.time()))
                filename = f"{timestamp}_{filename}"
                file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
                file.save(file_path)
                
                print(f"📁 批量处理文件: {file_path}")
                
                # 调用OCR API
                result = call_ocr_api(file_path)
                
                results.append({
                    'filename': file.filename,
                    'success': result['success'],
                    'text': result.get('text', ''),
                    'confidence': result.get('confidence', 0),
                    'api_used': result.get('api_used', 'Unknown'),
                    'text_overlay': result.get('text_overlay'),
                    'error': result.get('error', '') if not result['success'] else None
                })
            else:
                results.append({
                    'filename': file.filename,
                    'success': False,
                    'text': '',
                    'confidence': 0,
                    'api_used': 'None',
                    'text_overlay': None,
                    'error': '不支持的文件格式'
                })
        
        return jsonify({
            'success': True,
            'results': results,
            'total': len(results),
            'successful': len([r for r in results if r['success']])
        })
        
    except Exception as e:
        print(f"批量OCR API错误: {str(e)}")
        return jsonify({'success': False, 'error': f'服务器错误: {str(e)}'})

@app.route('/api/test', methods=['GET'])
def test_api():
    """测试API状态"""
    api_status = []
    
    for api_config in OCR_APIS:
        status = {
            'name': api_config['name'],
            'type': api_config['type'],
            'configured': True
        }
        
        if api_config['type'] == 'shiliuai':
            status['configured'] = bool(api_config.get('appcode'))
            if not status['configured']:
                status['message'] = '未配置APPCODE，请在config.py中设置'
        
        api_status.append(status)
    
    return jsonify({
        'success': True,
        'message': 'OCR服务运行正常',
        'apis': api_status,
        'upload_folder': UPLOAD_FOLDER,
        'max_file_size': '5MB',
        'supported_formats': list(ALLOWED_EXTENSIONS)
    })

if __name__ == '__main__':
    print("=" * 60)
    print("🚀 OCR服务启动中...")
    print("📍 访问地址: http://localhost:5000")
    print("🔗 支持十六AI OCR API + OCR.space备用")
    print("📁 上传目录: uploads/")
    print("💡 支持格式: JPG, PNG, BMP, PDF, TIFF, GIF")
    print("📏 最大文件: 5MB")
    print("🌐 支持中文识别")
    print("🧪 测试API: http://localhost:5000/api/test")
    if not SHILIUAI_APPCODE:
        print("⚠️  请在config.py中配置您的十六AI APPCODE")
        print("🔗 获取地址: https://market.shiliuai.com/account/get_api_account")
    print("=" * 60)
    app.run(debug=True, host='0.0.0.0', port=5000)